package com.llj.chatbidemo.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.llj.chatbidemo.config.ChatAITool;
import com.llj.chatbidemo.config.MetadataHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class ChatBIServiceImpl {
    @Autowired
    private MetadataHolder metadataHolder;


    @Autowired
    private ChatAITool chatAITool; // 应能正常注入
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 核心提示词模板（可根据业务扩展）
    private static final String ANALYSIS_PROMPT = """
        你是一个高级数据分析专家（ChatBI），请根据用户问题、数据库元数据和查询结果进行分析。
        
        ### 数据库元数据（JSON格式）：
        {metadata}
        
        ### 用户问题：
        {question}
        
        ### 最新查询结果（JSON）：
        {result}
        
        请按以下步骤思考：
        1. 用1句话总结数据趋势
        2. 指出2个关键数据点
        3. 给出1个业务建议
        4. 推荐1种可视化图表类型（柱状图、折线图等）
        
        严格按照该JSON格式返回，不要输入其他多余的字符：
        {
          "summary": "...",
          "key_points": ["...", "..."],
          "recommendation": "...",
          "chart_type": "..."
        }
        """;

    // 自然语言转SQL
    public String naturalLanguageToSQL(String question) {
        String prompt = """
          根据数据库结构和用户问题生成规范的MySQL查询，严格遵循以下协议：
            ### 数据库元数据：%s
            ### 用户问题：
                %s
            ### 生成协议（必须满足）：
             1. 【语句结构】
                ✓ 必须包含完整子句：SELECT → FROM → [JOIN] → WHERE → ORDER BY → LIMIT
                ✓ SELECT必须显式列出字段（禁用SELECT *）
                ✓ FROM必须指定主表
             2. 【表关联】
                ✓ 多表查询必须使用显式JOIN（INNER/LEFT）
                ✓ JOIN必须带ON条件
                ✓ 必须为所有表定义别名
             3. 【字段规则】
                ✓ 至少包含1个业务描述字段
                ✓ 时间相关查询必须选择时间字段
                ✓ 统计类问题必须用聚合函数
             4. 【条件处理】
                ✓ 用户问题中的过滤值必须转为WHERE条件
             5. 【结果规范】
                ✓ 按业务逻辑排序（时间正序/倒序，数值大小等）
                ✓ LIMIT 10必须作为最后子句
                ✓ 字符串值用单引号包裹
           ### 输出要求：
            - 只用标准SQL，不要用方言
            - 包含LIMIT 10
            - 表名用反引号包裹
            - 输出必须为纯SQL语句，不要包含任何其他字符（如```sql等代码块符号）
            - 输出只有SQL，不要解释
          """.formatted(metadataHolder.getMetadata(), question);

        try {
            // 调用火山引擎AI
            return chatAITool.askQuestion(prompt);
        } catch (Exception e) {
            throw new RuntimeException("SQL生成失败: " + e.getMessage());
        }
    }

    //根据用户问题与数据结果进行数据分析
    public String analyzeData(String question, String sql) {
        // 执行SQL获取结果
        String result = executeSQL(sql);

        // 构造分析提示
        String fullPrompt = ANALYSIS_PROMPT
                .replace("{metadata}", metadataHolder.getMetadata().toJSONString())
                .replace("{question}", question)
                .replace("{result}", result);
        try {
            // 调用OpenAI API
            return chatAITool.askQuestion(fullPrompt);
        } catch (Exception e) {
            throw new RuntimeException("Failed to call OpenAI API" + e.getMessage());
        }
    }

    public String explainMetric(String metricName) {
        String prompt = """
            作为数据分析助手，请解释以下指标的业务含义：
            
            数据库元数据：%s
            
            指标名称：%s
            
            要求：
            1. 用非技术人员能理解的语言
            2. 包含计算方式（如果有）
            3. 说明正常值范围
            4. 给出1个应用示例
            """.formatted(metadataHolder.getMetadata(), metricName);

        return chatAITool.askQuestion(prompt);
    }

    // 在原有 ChatBIService 中添加方法
    public String generateEChartsConfig(String sql, String question) {
        String echartsExample = """
        {
          "title": {
            "text": "月度销售趋势 (示例)",
            "left": "center"
          },
          "tooltip": {
            "trigger": "axis"
          },
          "xAxis": {
            "type": "category",
            "data": ["1月", "2月", "3月", "4月", "5月", "6月"]
          },
          "yAxis": {
            "type": "value"
          },
          "series": [{
            "name": "销售额",
            "type": "bar",
            "data": [6500, 8200, 7200, 9500, 7300, 8800],
            "itemStyle": {
              "color": "#409eff",
              "borderRadius": [4, 4, 0, 0]
            },
            "emphasis": {
              "itemStyle": {
                "shadowBlur": 10,
                "shadowColor": "rgba(64, 158, 255, 0.5)"
              }
            }
          }]
        }""";

        //String dataStr = (data instanceof String) ? (String) data : data.toString();
        String EC_Prompt = """
        根据用户提供的数据集和问题描述，生成符合ECharts规范的配置选项(option)。请严格遵循以下步骤：
        
        ### 数据集（JSON格式）：
        %s
        
        ### 用户问题：
        %s
        
        ### 图表类型选择规则：
        根据数据特征自动选择图表类型：
        1. 趋势分析（时间序列） → 折线图
           - 示例：每月预约量变化
        2. 类别对比（离散数据） → 柱状图/条形图
           - 示例：不同剧本的评分对比
        3. 比例分布 → 饼图/环形图
           - 示例：各状态场次占比
        4. 相关性分析 → 散点图/热力图
           - 示例：玩家数量与评分的关系
        5. 地理数据 → 地图
           - 示例：用户地域分布
        ### 生成规则：
        1. 自动识别最佳图表类型（柱状图/折线图/饼图等）
        2. 包含完整的配置结构（title/xAxis/yAxis/series等）
        3. 数据预处理（排序/过滤/聚合）
        4. 智能颜色编码（使用企业级配色方案）
        5. 响应式布局支持（resizeable: true）
        
        示例参考：
        %s
        
        要求：
        - 输出纯净JSON，无额外文本
        - 禁止在返回内容中出现js函数
        - 严格遵循ECharts官方规范
        - 对无法可视化的数据返回错误结构：
        { "error": true, "message": "原因说明" }
        
        请直接输出配置JSON：
        """.formatted(executeSQL(sql), question, echartsExample);

        try {
            String json = chatAITool.askQuestion(EC_Prompt);
            return json;
        } catch (Exception e) {
            return "{ \"error\": true, \"message\": \"配置生成失败: " + e.getMessage() + "\" }";
        }
    }

    //需要获取数据库元数据时调用
    public JSONObject getMetadata() {
        JSONObject meta = metadataHolder.getMetadata();
        String tableName = meta.getJSONArray("tables")
                .getJSONObject(0)
                .getString("physical_name");
        return meta;
    }

    //执行sql语句
    public String executeSQL(String sql) {
        // 执行SQL获取结果
        String result = JSON.toJSONString(jdbcTemplate.queryForList(sql));
        return result;
    }
}
